package dijkstra;

import java.util.LinkedList;

import jeu.Game;
import jeu.Move;

public class Dijkstra extends Game {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	LinkedList<Integer> state;
	int taille, objectif;
	LinkedList<Move> history;

	public Dijkstra(int objectif){
		//objectif doit etre > 3
		if(objectif >=3){
			state = new LinkedList<Integer>();
			state.add(new Integer(0));
			state.addFirst(new Integer(1));
			this.objectif = objectif;
			taille = 2;
			history = new LinkedList<Move>();
			history.add(new DijkstraMove(objectif));
		} else {
			System.out.println("Objectif trop faible");
		}
	}
	
	@Override
	public LinkedList<Move> getPossibleMove() {
		LinkedList<Move> result = new LinkedList<Move>();
		for(int i = 0; i < 3; i++){
			if(checkMove(i)){
				result.add(new DijkstraMove(i));
			}
		}
		return result;
	}
	
	private boolean checkMove(int m){
		if(taille == 0){
			return true;
		}
		state.addFirst(m);
		//System.out.println(state);
		
		boolean check = false;
		for(int i = 1; i <= (taille+1)/2; i++){
			check = false;
			for(int j = 0; j < i; j++){
				//System.out.println("Je compare " + i + " et " + j);
				if(state.get(j).intValue() != state.get(i+j).intValue()){

					check = true;
				}
			}
			if(!check){	break;}
		}
		
		state.removeFirst();
		return check;
	}

	@Override
	public boolean applyMove(Move m) {
		DijkstraMove move = (DijkstraMove) m;
		if(move.isInit){
			System.out.println("Je ne sais pas ajouter un mouv d'initialisation");
			return false;
		}
		if(checkMove(move.i)){
			state.addFirst(move.i);
			taille ++;
			history.addLast(m);
			return true;
		} else {
			System.out.println("Ce mouvement est illegal");
			return false;
		}
	}

	@Override
	public boolean isWin() {
		return (taille >= objectif);
	}

	@Override
	public boolean undoLastMove() {
		if(history.peekLast().isInit()){
			return false;
		}
		state.removeFirst();
		taille --;
		history.removeLast();
		return true;
	}

	@Override
	public LinkedList<Move> getHistory() {
		return history;
	}
	
	public boolean isSameResult(LinkedList<Integer> l) {
		//TODO corriger
		//return l.equals(state);
		if(l.size() != taille){
			return false;
		}
		for(int i = 0; i < taille; i++){
			if(l.get(i) != state.get(i)){
				
			}
		}
		return true;
	}
	
	public boolean isSameResult(Dijkstra g) {
		return isSameResult(g.state);
	}

	@Override
	public boolean isSameResult(Game g) {
		return isSameResult((Dijkstra) g) ;
	}

	@Override
	public String instruction() {
		String result = "";
		for(Move c : history){
			result += c.instruction() + "\n";
		}
		return result;
	}

	@Override
	public void printState() {
		System.out.println(getState());
	}

	@Override
	public String getState() {
		String result = "";
		for(int c : state){
			result = c + result;
		}
		return result;
	}

}
